package com.atguigu.tingshu.listener;


import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class OrderMqListener {
    @Autowired
    private OrderInfoService  orderInfoService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = RabbitConstant.PAYMENT_STATE_QUEUE , durable = "true"),
                    exchange = @Exchange(value = RabbitConstant.PAYMENT_EXCHANGE , type = "topic"),
                    key = {RabbitConstant.PAYMENT_STATE_RK}
            )
    })
    @SneakyThrows
    public void updateOrderStatus(Channel channel , Message message ,
                                  Map<String,String> map){
        //更新订单状态
        try {
            if(!CollectionUtils.isEmpty(map)){
                String orderNo = map.get("orderNo");
                String status = map.get("status");
                String orderStatus;
                switch (status){
                    case "1402":
                        //已支付
                        orderStatus = SystemConstant.ORDER_STATUS_PAID;
                        break;
                    default:
                        orderStatus = SystemConstant.ORDER_STATUS_FAIL;
                        break;
                }

                orderInfoService.update(Wrappers.lambdaUpdate(OrderInfo.class)
                        .eq(OrderInfo::getOrderNo , orderNo)
                        .eq(OrderInfo::getOrderStatus , SystemConstant.ORDER_STATUS_UNPAID)
                        .set(OrderInfo::getOrderStatus , orderStatus));//更新订单状态
            }

            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            if(message.getMessageProperties().isRedelivered()){
                log.error("订单支付状态更新失败，消息内容：{}" , JSONObject.toJSONString(map));
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                log.warn("订单支付状态更新失败，尝试重试，消息内容：{}" , JSONObject.toJSONString(map));
                channel.basicNack(message.getMessageProperties().getDeliveryTag() , false,true);
            }
        }


    }



    @SneakyThrows
    @RabbitListener(queues = {RabbitConstant.ORDER_DEAD_QUEUE})
    public void cancelOrder(Channel channel, Message message, String orderNo){
        //延迟关单业务
        //如果orderNo的订单是待支付状态，那么默认15分钟未支付，关闭订单
        try {
            orderInfoService.update(Wrappers.lambdaUpdate(OrderInfo.class)
                    .eq(OrderInfo::getOrderNo, orderNo)
                    .eq(OrderInfo::getOrderStatus, SystemConstant.ORDER_STATUS_UNPAID)
                    .set(OrderInfo::getOrderStatus, SystemConstant.ORDER_STATUS_CANCEL));

            //关单成功： 关闭微信支付交易记录
            rabbitTemplate.convertAndSend(
                    RabbitConstant.PAYMENT_EXCHANGE ,
                    RabbitConstant.PAYMENT_CLOSE_RK ,
                    orderNo
            );
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
           if(message.getMessageProperties().isRedelivered()){
               log.error("订单超时未支付，订单号：{}" , orderNo);
               channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);//丢弃消息
               throw new RuntimeException(e);
           }else {
               log.warn("订单延迟关单失败，尝试重新投递，订单号：{},",orderNo);
               channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                       false,true);
           }

        }

    }

}
